package ntd.util.frame.storage.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.stream.StreamUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.BucketInfo;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.OSSObject;
import io.minio.MinioClient;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import ntd.util.frame.storage.NtdStorage;
import ntd.util.frame.storage.bo.StorageConfig;
import ntd.util.UtilCatch;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Date;
import java.util.stream.Stream;

@Slf4j
@Data
public class NtdStorageAliyun implements NtdStorage {

    private StorageConfig config;

    private OSS ossClient;

    public NtdStorageAliyun(StorageConfig config) {
        this.config = config;
        ossClient = new OSSClientBuilder().build(config.getUrl(), config.getAppKey(), config.getAppSecret());
    }

    @Override
    public void store(String bucketName, byte[] bytes, String keyName) {
        initBucket(bucketName);
        ossClient.putObject(bucketName, keyName, new ByteArrayInputStream(bytes));
    }

    @Override
    public InputStream loadInputStream(String bucketName, String name) {
        OSSObject ossObject = ossClient.getObject(bucketName, name);
        return ossObject.getObjectContent();
    }

    private void initBucket(String bucketName) {
        UtilCatch.tryCatchNoRes(() -> {
            if(!ossClient.doesBucketExist(bucketName)) {
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
        });
    }

    @Override
    public void delete(String bucketName, String keyName) {
        UtilCatch.tryCatchNoRes(() -> ossClient.deleteObject(bucketName, keyName));
    }

    @Override
    public String generateUrl(String bucketName, String keyName) {
        BucketInfo bucketInfo = ossClient.getBucketInfo(bucketName);
        CannedAccessControlList cannedACL = bucketInfo.getCannedACL();
        if (CannedAccessControlList.PublicRead.equals(cannedACL) || CannedAccessControlList.PublicReadWrite.equals(cannedACL)) {
            return config.getUrl() + "/" + bucketName + "/" + keyName;
        }
        return ossClient.generatePresignedUrl(bucketName, keyName, DateUtil.offsetHour(DateUtil.date(), 6)).getPath();
    }
}
